package com.apes.framework.plugin.mq;

import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.esb.api.Request;
import com.apes.framework.plugin.esb.processor.Processor;
import com.apes.framework.jpa.lock.IsTryAgain;
import com.apes.oap.RopRequestContext;
import com.apes.oap.impl.SimpleRopRequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * 功能：消费者适配器
 *
 * @author xul
 * @create 2017-12-07 18:50
 */

@Component("consumerAdapter")
public class ConsumerAdapter {

    @Autowired
    TransactionTemplate transactionTemplate;

    public boolean consume(Processor processor, MQEvent ropEvent, boolean isTransaction) {
        RopRequestContext context = new SimpleRopRequestContext(ropEvent.getRopContext());
        SimpleRequest message = new SimpleRequest();
        message.setRopRequestContext(context);
        message.setBody(ropEvent.getMessage().getBody());
        if (isTransaction) {
            return process(processor, message);
        }
        return invoke(processor, message);
    }

    /**
     * 编程式事务
     */
    @IsTryAgain
    private boolean process(Processor processor, SimpleRequest message) {
        return (Boolean) transactionTemplate.execute((TransactionCallback) status -> {
            try {
                return invoke(processor, message);
            } catch (Exception e) {
                status.isRollbackOnly();
                throw e;
            }
        });
    }

    private boolean invoke(Processor processor, Request request) {
        Object result = processor.process(request);
        if (result instanceof Boolean) return (boolean) result;
        return true;
    }


}
